<template>
  <div class="flex space-x">
    <div class="group" v-for="(item,groupIndex) in groupData" :key="groupIndex" ref="groups">
      <div
          @dragstart="handleDragStart($event, groupIndex, itemIndex, item)"
          @dragend="handleDragEnd($event, groupIndex, itemIndex, item)"
          @dragenter="handleDragEnter($event, groupIndex, itemIndex, item)"
          ref="items"
          class="item" v-for="(item, itemIndex) in item" :key="item.id">{{ item.name }}
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import {Component, Vue} from "vue-property-decorator"

interface DragItem {
  id: number,
  name: string
}

@Component
export default class GroupDrag extends Vue {
  $refs!: {
    items: HTMLDivElement[],
    groups: HTMLDivElement[]
  }
  groupData = [
    [
      {id: 1, name: "g_1_1"},
      {id: 2, name: "g_1_2"}
    ],
    [
      {id: 3, name: "g_2_1"},
      {id: 4, name: "g_2_2"}
    ],
    [
      {id: 5, name: "g_3_1"},
      {id: 6, name: "g_3_2"},
      {id: 7, name: "g_3_3"},
      {id: 8, name: "g_3_4"},
      {id: 9, name: "g_3_5"},
      {id: 10, name: "g_3_6"},
    ]
  ]

  renderData: any = []

  ele!: HTMLDivElement
  groupIndex!: number
  index!: number
  item!: DragItem

  mounted(): void {
    // this.renderData = [...this.groupData]
    this.$nextTick(() => {
      this.$refs.items.forEach(item => item.draggable = true)
    })
  }

  handleDragStart(e: DragEvent, groupIndex: number, index: number, item: DragItem): void {
    this.ele = e.target as HTMLDivElement
    this.groupIndex = groupIndex
    this.index = index
    this.item = item
  }

  handleDragEnd(e: DragEvent, groupIndex: number, index: number, item: DragItem): void {
    console.log("end", e, item.name)
  }

  handleDragEnter(e: DragEvent, groupIndex: number, index: number, item: DragItem): void {
    const targetGroup = this.$refs.groups[groupIndex]
    if (groupIndex !== this.groupIndex) {  // 换组逻辑
      this.$refs.groups[groupIndex].appendChild(this.ele)
    } else {  // 同组逻辑
      console.log(this.index, index)
      if (this.index === index) {
        return
      } else if (this.index > index) {   // 向上移动
        targetGroup.insertBefore(this.ele, e.target as HTMLDivElement)
      } else if (this.index < index) { // 向下移动
        const target = (e.target as HTMLDivElement).nextElementSibling
        if (target) {
          targetGroup.insertBefore(this.ele, target)
        } else {
          targetGroup.appendChild(this.ele)
        }
      }
    }
  }


}
</script>

<style scoped lang="scss">
.group {
  user-select: none;
  margin: 10px;
  width: 200px;
  height: 500px;
  border: 1px solid #ccc;

  .item {
    text-align: center;
    background-color: skyblue;
    margin: 5px;
    padding: 5px;
    border-radius: 5px;
  }
}
</style>
